package priv.xakml.demo.boot18mybatisplus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import priv.xakml.demo.boot18mybatisplus.mapper.TestMapper;
import priv.xakml.demo.boot18mybatisplus.model.TestUpdateModel;
import priv.xakml.demo.boot18mybatisplus.pojo.Test;
import priv.xakml.demo.boot18mybatisplus.service.ITestService;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author lhx
 * @date 2022-05-26 11:06
 **/
@Service
public class TestService extends ServiceImpl<TestMapper, Test>
    implements ITestService {


    /**
     * 查询范围
     * @param start
     * @param end
     * @return
     */
    public List<Test> getRange(long start, long end){
        QueryWrapper<Test> testQueryWrapper = new QueryWrapper<>();
        testQueryWrapper.lambda().gt(Test::getId,start)
                .lt(Test::getId,end);
        List<Test> list = this.list(testQueryWrapper);
        return list;
    }
//Mybatis-plus 查询指定字段 select
//参考链接： https://blog.csdn.net/qq_38534107/article/details/124047299

    public List<Test> getRangFields(long start, long end){
        QueryWrapper<Test> testQueryWrapper = new QueryWrapper<>();
        testQueryWrapper.lambda().gt(Test::getId,start).select(Test::getLongValue,Test::getId)
                .lt(Test::getId,end);
        List<Test> list = this.list(testQueryWrapper);
        return list;
    }

    @Cacheable(value = "get_test",key = "#id")
    public Test get(long id){
       return this.getById(id);
    }

    @Override
    public int updateLongValueBatch(List<TestUpdateModel> list) {
        int i = baseMapper.updateLongValueBatch(list);
        return i;
    }

    @Override
    @Transactional
    public boolean batchUpdateByIds(List<Long> ids) {
        if(ids.size() > 10){
            return batchUpdateByIds(ids,10);
        }
        else{
            long rowsAffect = baseMapper.batchUpdateLongValueByIds(ids);
            //if(obj.getClass().equals(Integer.class))
            return rowsAffect  > 0;
        }

    }

    /**
     *
     * ids集合中，如果有15的倍数，则抛出runtimeException,触发事务回滚操作
     * @param ids
     * @param batchSize
     * @return
     */
    @Override
    public  boolean batchUpdateByIds(List<Long> ids,int batchSize){
        boolean isOK = true;
        List<List<Long>> blocks = splitList(ids, batchSize);
        for (List<Long> block : blocks) {
            if(block.stream().anyMatch(i->i % 15 == 0 ))
                throw new RuntimeException("手动抛出异常");
            long rowsAffect = baseMapper.batchUpdateLongValueByIds(block);
            if (rowsAffect <= 0)
                isOK = false;
        }
        if(!isOK)
            System.out.println("回滚事务");
        return isOK;
    }

    public <T> List<List<T>> splitList(List<T> list,int chunkSize){
        int numOfChunks = (int) Math.ceil((double)list.size()/chunkSize);
        return IntStream.range(0,numOfChunks)
                .mapToObj(i->list.subList(i*chunkSize,Math.min((i+1) * chunkSize,list.size())))
                .collect(Collectors.toList());
    }
}
